/*
 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang;

/**
 *
 * {@code Byte}是将基本类型{@code byte}包装成了一个对象.
 * 一个{@code Byte}类型的对象只包含一个类型为{@code byte}的字段.
 *
 * <p>另外,该类还提供了多种将{@code byte}转换为{@code String}
 * 以及将{@code String}转换为{@code byte}的方法,
 * 并且还提供了一些其它很有用的处理{@code byte}的方法.
 *
 * @author  Nakul Saraiya
 * @author  Joseph D. Darcy
 * @see     java.lang.Number
 * @since   JDK1.1
 */
public final class Byte extends Number implements Comparable<Byte> {

    /**
     * 常量,保存{@code byte}的最小值,-2<sup>7</sup>
     */
    public static final byte   MIN_VALUE = -128;

    /**
     * 常量,保存{@code byte}的最大值, 2<sup>7</sup>-1.
     */
    public static final byte   MAX_VALUE = 127;

    /**
     * 代表基本类型{@code byte}的{@code Class}实例.
     */
    @SuppressWarnings("unchecked")
    public static final Class<Byte>     TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");

    /**
     * 返回表示指定{@code byte}的新的{@code String}对象{@code byte}.
     * 假定基数为10(译者注:Byte.toString实际上调用的是java.lang.Integer#toString(int,int),基数为10指的也就是该方法的第二个参数).
     *
     * @param b 要转换的{@code byte}
     * @return 代表指定{@code byte}的字符串
     * @see java.lang.Integer#toString(int)
     */
    public static String toString(byte b) {
        return Integer.toString((int)b, 10);
    }

    private static class ByteCache {
        private ByteCache(){}

        static final Byte cache[] = new Byte[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Byte((byte)(i - 128));
        }
    }

    /**
     * 返回一个代表指定{@code byte}值的{@code Byte}实例.
     * 如果不需要一个新的{@code Byte}实例,应优先采用此方法,
     * 而不是构造方法{@link #Byte(byte)},
     * 因为该方法会缓存所有的byte values,因而可能会明显的提高空间和时间性能.
     *
     * @param  b a byte value.
     * @return a {@code Byte} instance representing {@code b}.
     * @since  1.5
     */
    public static Byte valueOf(byte b) {
        final int offset = 128;
        return ByteCache.cache[(int)b + offset];
    }

    /**
     * 将string参数解析成一个有符号{@code byte},其基数由第二个参数决定.
     * 除了第一个字符可以为表示负数的ASCII负号{@code '-'} ({@code '\u005Cu002D'})
     * 或者是表示正数的ASCII加号{@code '+'} ({@code '\u005Cu002B'})外.
     * string里面的字符必须全部为指定基数的数字(这由{@link java.lang.Character#digit(char,int)}是否返回非负值决定),
     * 返回解析得到的{@code byte}值.
     *
     * <p>如果出现下列任何一种情况,将会抛出异常{@code NumberFormatException}:
     * <ul>
     * <li> 第一个参数为{@code null}或者是一个长度为0的字符串.
     *
     * <li> 基数小于 {@link java.lang.Character#MIN_RADIX}或者大于{@link java.lang.Character#MAX_RADIX}.
     *
     * <li> 字符串中的任意一个字符不是指定的数字,
     * 除了第一个字符可以为表示负数的ASCII负号{@code '-'} ({@code '\u005Cu002D'})
     * 或者是表示正数的ASCII加号{@code '+'} ({@code '\u005Cu002B'})外,
     * 当然这个时候要保证字符串的长度超过1.
     *
     * <li>string代表的字符串并不是一个{@code byte}值
     * {@code byte}.
     * </ul>
     *
     * @param s         包含待解析的{@code byte}的{@code String}
     *
     * @param radix     解析{@code s}时所采用的基数
     * @return          指定基数的string参数所代表的{@code byte}
     * @throws          NumberFormatException string参数并不包含可解析的{@code byte}.
     */
    public static byte parseByte(String s, int radix)
        throws NumberFormatException {
        int i = Integer.parseInt(s, radix);
        if (i < MIN_VALUE || i > MAX_VALUE)
            throw new NumberFormatException(
                "Value out of range. Value:\"" + s + "\" Radix:" + radix);
        return (byte)i;
    }

    /**
     * 将string参数作为一个有符号的十进制{@code byte}.
     * 除了第一个字符可以为表示负数的ASCII负号{@code '-'} ({@code '\u005Cu002D'})
     * 或者是表示正数的ASCII加号{@code '+'} ({@code '\u005Cu002B'})外,
     * 这个字符串里面的字符必须都是十进制数字.
     * 返回解析得到的{@code byte}值.
     * 返回值等同于以该string和10为基数的{@link #parseByte(java.lang.String, int)}方法的返回值.
     *
     * @param s         包含待解析的{@code byte}的{@code String}
     * @return          十进制格式的参数所表示的{@code byte}值
     * @throws          NumberFormatException string参数并不包含可解析的{@code byte}.
     */
    public static byte parseByte(String s) throws NumberFormatException {
        return parseByte(s, 10);
    }

    /**
     * 返回一个保存由{@code String}指定的值的{@code Byte}对象,
     * 该string参数由第二个参数指定的基数解析.
     * 第一个参数被解释为用第二个参数所指定的基数表示一个有符号的{@code byte},
     * 等同于将参数指定给{@link #parseByte(java.lang.String,int)}方法一样.
     * 返回结果是一个表示该string所指定的{@code byte}值的{@code Byte}对象.
     *
     * <p> 换句话说,该方法返回一个等价于以下代码的{@code Byte}对象:
     *
     * <blockquote>
     * {@code new Byte(Byte.parseByte(s, radix))}
     * </blockquote>
     *
     * @param s         要解析的字符串
     * @param radix     用来解析{@code s}的基数
     * @return          保存由指定基数的string参数所表示的值的{@code Byte}对象.
     * @throws          NumberFormatException string参数并不包含可解析的{@code byte}.
     */
    public static Byte valueOf(String s, int radix)
        throws NumberFormatException {
        return valueOf(parseByte(s, radix));
    }

    /**
     * 返回一个保存由{@code String}指定的值的{@code Byte}对象.
     * 该参数被解析成为个有符号的十进制的{@code byte},
     * 等同于将参数指定给{@link #parseByte(java.lang.String)}方法一样.
     * 返回结果是一个表示该string所指定的{@code byte}值的{@code Byte}对象.
     *
     * <p> 换句话说,该方法返回一个等价于以下代码的{@code Byte}对象:
     *
     * <blockquote>
     * {@code new Byte(Byte.parseByte(s))}
     * </blockquote>
     *
     * @param s         要解析的字符串
     * @return          保存由string参数所表示的值的{@code Byte}对象.
     * @throws          NumberFormatException string参数并不包含可解析的{@code byte}.
     */
    public static Byte valueOf(String s) throws NumberFormatException {
        return valueOf(s, 10);
    }

    /**
     * 将一个{@code String}解码成{@code Byte}.
     * 接受按照下列语法给出的十进制、十六进制和八进制数:
     *
     * <blockquote>
     * <dl>
     * <dt><i>DecodableString:</i>
     * <dd><i>符号<sub>可选</sub> 十进制数</i>
     * <dd><i>符号<sub>可选</sub></i> {@code 0x} <i>十六进制数</i>
     * <dd><i>符号<sub>可选</sub></i> {@code 0X} <i>十六进制数</i>
     * <dd><i>符号<sub>可选</sub></i> {@code #} <i>十六进制数</i>
     * <dd><i>符号<sub>可选</sub></i> {@code 0} <i>八进制数</i>
     *
     * <dt><i>符号:</i>
     * <dd>{@code -}
     * <dd>{@code +}
     * </dl>
     * </blockquote>
     *
     * 在<cite>The Java&trade; Language Specification</cite>　3.10.1章节中有关于
     * <i>DecimalNumeral</i>, <i>HexDigits</i>, and <i>OctalDigits</i>的定义,
     * 需要注意的是在这里数字间的下划线并不被允许.
     *
     * <p>对符号(可选)和/或基数说明符("{@code 0x}", "{@code 0X}","{@code #}", 或者前导0)
     * 后面的字符序列进行解析,就如同使用带指定基数(10, 16, or 8)的{@code Byte.parseByte}方法一样,
     * 这个字符序列必须表示一个正值(译者注:0也可以),否则将会抛出{@link NumberFormatException}异常.
     * 如果{@code String}的第一个字符是负号,那么将会返回负数.
     * {@code String}中不允许出现空白字符.
     *
     * @param     nm 要解码的{@code String}.
     * @return   返回一个保存由{@code nm}表示的{@code byte}值的{@code Byte}对象
     * @throws  NumberFormatException  string参数并不包含可解析的{@code byte}.
     * @see java.lang.Byte#parseByte(java.lang.String, int)
     */
    public static Byte decode(String nm) throws NumberFormatException {
        int i = Integer.decode(nm);
        if (i < MIN_VALUE || i > MAX_VALUE)
            throw new NumberFormatException(
                    "Value " + i + " out of range from input " + nm);
        return valueOf((byte)i);
    }

    /**
     * {@code Byte}的值.
     *
     * @serial
     */
    private final byte value;

    /**
     * 构建一个新分配的{@code Byte}对象,以表示指定{@code byte}值.
     *
     * @param value     将要用{@code Byte}去表示的值.
     */
    public Byte(byte value) {
        this.value = value;
    }

    /**
     * 构建一个新分配的{@code Byte}对象,以表示{@code String}参数所指定的{@code byte}值.
     * 这个string采用基数为10的{@code parseByte}方法来转换成{@code byte}值.
     *
     * @param s  打算转换成{@code Byte}的{@code String}
     *
     * @throws   NumberFormatException string参数并不包含可解析的{@code byte}.
     * @see      java.lang.Byte#parseByte(java.lang.String, int)
     */
    public Byte(String s) throws NumberFormatException {
        this.value = parseByte(s, 10);
    }

    /**
     * 将当前{@code Byte}作为一个{@code byte}值返回
     */
    public byte byteValue() {
        return value;
    }

    /**
     * 经过扩展基本转换(Widening Primitive Conversions)后将当前{@code Byte}作为一个{@code short}值返回
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public short shortValue() {
        return (short)value;
    }

    /**
     * 经过扩展基本转换(Widening Primitive Conversions)后将当前{@code Byte}作为一个{@code int}值返回
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public int intValue() {
        return (int)value;
    }

    /**
     * 经过扩展基本转换(Widening Primitive Conversions)后将当前{@code Byte}作为一个{@code long}值返回
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public long longValue() {
        return (long)value;
    }

    /**
     * 经过扩展基本转换(Widening Primitive Conversions)后将当前{@code Byte}作为一个{@code float}值返回
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public float floatValue() {
        return (float)value;
    }

    /**
     * 经过扩展基本转换(Widening Primitive Conversions)后将当前{@code Byte}作为一个{@code double}值返回
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public double doubleValue() {
        return (double)value;
    }

    /**
     * 返回表示此{@code Byte}的值的{@code String}对象.
     * 该值被转换成有符号的十进制表示形式, 并作为一个string返回,
     * 正如将{@code byte}值作为一个参数指定给{@link java.lang.Byte#toString(byte)}方法所返回的一样.
     *
     * @return  以基数10表示的此对象值的字符串.
     */
    public String toString() {
        return Integer.toString((int)value);
    }

    /**
     * 返回此{@code Byte}的哈希码(hash code);等价于请求{@code intValue()}方法.
     *
     * @return a hash code value for this {@code Byte}
     */
    @Override
    public int hashCode() {
        return Byte.hashCode(value);
    }

    /**
     * 返回指定{@code byte}值的哈希值(hash value); 等同于{@code Byte.hashCode()}.
     *
     * @param value 要hash的值
     * @return 指定{@code byte}值的哈希码的值(hash code value).
     * @since 1.8
     */
    public static int hashCode(byte value) {
        return (int)value;
    }

    /**
     * 将当前对象与指定对象进行对比.
     * 当且仅当参数不为{@code null}并且是一个跟当前对象包含了同样{@code byte}值的{@code Byte}对象时,
     * 返回{@code true}.
     *
     * @param obj       要比较的对象
     * @return          是同一对象,返回{@code true};
     *                  否则返回{@code false}.
     */
    public boolean equals(Object obj) {
        if (obj instanceof Byte) {
            return value == ((Byte)obj).byteValue();
        }
        return false;
    }

    /**
     * 数值上比较两个{@code Byte}对象.
     *
     * @param   anotherByte   要比较的{@code Byte}对象.
     * @return  进行有符号对比,
     *          如果此{@code Byte}等于参数{@code Byte},那么返回{@code 0};
     *          如果此{@code Byte}小于参数{@code Byte},那么一个小于{@code 0}的值;
     *          如果此{@code Byte}大于参数{@code Byte},那么一个大于{@code 0}的值;
     *          (译者注:简单地说,返回结果为两个{@code Byte}相减的值)
     * @since   1.2
     */
    public int compareTo(Byte anotherByte) {
        return compare(this.value, anotherByte.value);
    }

    /**
     * 数值上比较两个{@code byte}值.
     * 返回值跟以下代码返回值一样:
     * <pre>
     *    Byte.valueOf(x).compareTo(Byte.valueOf(y))
     * </pre>
     *
     * @param  x 要比较的第一个{@code byte}值
     * @param  y 要比较的第二个{@code byte}值
     * @return 如果{@code x == y},返回{@code 0};
     *         如果{@code x < y},返回小于{@code 0}的值;
     *         如果{@code x > y},返回大于{@code 0}的值;
     *         (译者注:简单地说,返回{@code x - y}的值)
     * @since 1.7
     */
    public static int compare(byte x, byte y) {
        return x - y;
    }

    /**
     * 将参数按照无符号的转换方式转换为{@code int}.
     * 在无符号转换成{@code int}的过程中,{@code int}里面高位的24 bits全部为0,
     * 低位的8 bits等于{@code byte}参数的bits.
     *
     * 因此,0和正的{@code byte}值会被映射成一个数值上相等的{@code int}值,
     * 而负的{@code byte}值会被映射成一个数值上等于输入值加上2<sup>8</sup>的{@code byte}值.
     *
     * @param  x 打算转换成无符号{@code int}类型的值
     * @return 通过无符号转换将参数转换成的{@code int}值
     * @since 1.8
     */
    public static int toUnsignedInt(byte x) {
        return ((int) x) & 0xff;
    }

    /**
     * 将参数按照无符号的转换方式转换为{@code long}.
     * 在无符号转换成{@code long}的过程中,{@code long}里面高位的56 bits全部为0,
     * 低位的8 bits等于{@code byte}参数的bits.
     *
     * 因此,0和正的{@code byte}值会被映射成一个数值上相等的{@code long}值,
     * 而负的{@code byte}值会被映射成一个数值上等于输入值加上2<sup>8</sup>的{@code byte}值.
     *
     * @param  x 打算转换成无符号{@code long}类型的值
     * @return 通过无符号转换将参数转换成的{@code long}值
     * @since 1.8
     */
    public static long toUnsignedLong(byte x) {
        return ((long) x) & 0xffL;
    }


    /**
     * 以二进制补码的形式表示{@code byte}值所用的位数.
     *
     * @since 1.5
     */
    public static final int SIZE = 8;

    /**
     * 以二进制补码的形式表示{@code byte}值所用的字节数.
     *
     * @since 1.8
     */
    public static final int BYTES = SIZE / Byte.SIZE;

    /** 采用来自JDK 1.1的serialVersionUID. 为了兼容 */
    private static final long serialVersionUID = -7183698231559129828L;
}
